<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn1">按钮1</button>
    <button id="btn2">按钮2</button>
    <script>
        // key和副作用函数的对应关系
        let data = {
            a: '修改后的按钮11',
            b: '修改后的按钮22'
        }
        let activeEffect;
        function effect (fn) {
            activeEffect = fn
            fn()
        }
        // 从Set => WeakMap
        const bucket = new WeakMap()
        const obj = new Proxy(data, {
            get(target, key) {
                if (!activeEffect) {
                    return target[key]
                }
                let depsMap = bucket.get(target)
                // 没有对应desMap
                if (!depsMap) {
                    bucket.set(target, (depsMap = new Map()))
                }
                let deps = depsMap.get(key)
                // 没有对应set
                if (!deps) {
                    depsMap.set(key, (deps = new Set()))
                }
                deps.add(activeEffect)
                return target[key]
            },
            set(target, key, newVal) {
                target[key] = newVal
                let depsMap = bucket.get(target)
                if (!depsMap) return 
                let effects = depsMap.get(key)
                // 执行副作用函数
                effects && effects.forEach(fn => fn())
            }
        })
        let btn1 = document.getElementById('btn1')
        let btn2 = document.getElementById('btn2')
        effect(() => {
            console.log('effect runs');
            // 按钮btn1读取obj.a的值，只有当修改obj.a的值时，effect函数才会再次执行
            btn1.innerText = obj.a
        })
    </script>
</body>
</html>